from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import login as auth_login, logout, authenticate, update_session_auth_hash
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.utils import timezone
from django.urls import reverse
from django.contrib.auth.models import User
from .models import UserProfile, EmailVerification, Address
from .forms import UserLoginForm, UserRegisterForm, UserProfileForm, AddressForm, PasswordChangeForm, ForgotPasswordForm, VerifyCodeForm, ResetPasswordForm
from django.core.mail import send_mail
from django.conf import settings
import uuid
from django.http import JsonResponse
import random
from django.views.decorators.http import require_POST
from django.core.cache import cache
from orders.models import Order
import json
import logging
from django.contrib.messages import get_messages
from django.views.decorators.csrf import csrf_exempt

logger = logging.getLogger(__name__)


def login_view(request):
    """
    用户登录视图 - 处理用户登录请求
    支持用户名或邮箱登录，支持记住登录状态
    支持AJAX请求和普通表单提交
    
    Args:
        request: HttpRequest对象
        
    Returns:
        HttpResponse或JsonResponse: 登录成功后重定向或返回JSON响应
    """
    if request.method == 'POST':
        form = UserLoginForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            remember = form.cleaned_data.get('remember_me')
            
            # 尝试使用用户名登录
            user = authenticate(username=username, password=password)
            
            # 如果用户名登录失败，尝试使用邮箱登录
            if user is None:
                try:
                    user_obj = User.objects.get(email=username)
                    user = authenticate(username=user_obj.username, password=password)
                except User.DoesNotExist:
                    user = None
            
            if user is not None:
                auth_login(request, user)
                
                # 设置会话过期时间
                if not remember:
                    request.session.set_expiry(0)  # 浏览器关闭即过期
                else:
                    # 设置为两周过期
                    request.session.set_expiry(14 * 24 * 60 * 60)
                
                # 获取next参数，优先从POST数据获取，其次从GET参数获取
                next_url = request.POST.get('next_url') or request.GET.get('next')
                
                if next_url:
                    # 检查是否是AJAX请求
                    if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                        return JsonResponse({
                            'success': True,
                            'message': '登录成功',
                            'redirect_url': next_url
                        })
                    else:
                        return redirect(next_url)
                else:
                    # 检查是否是AJAX请求
                    if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                        return JsonResponse({
                            'success': True,
                            'message': '登录成功',
                            'redirect_url': reverse('index')
                        })
                    else:
                        return redirect('index')
            else:
                if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                    return JsonResponse({
                        'success': False,
                        'message': '用户名或密码错误'
                    })
                else:
                    messages.error(request, '用户名或密码错误')
        else:
            # 表单验证失败
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                errors = {}
                for field, error_list in form.errors.items():
                    errors[field] = [str(error) for error in error_list]
                return JsonResponse({
                    'success': False,
                    'message': '登录信息有误',
                    'errors': errors
                })
    else:
        form = UserLoginForm()
    
    return render(request, 'user/login.html', {'form': form})


def register_view(request):
    """
    用户注册视图 - 处理用户注册请求
    创建未激活的用户账号，发送验证邮件
    支持AJAX请求和普通表单提交
    
    Args:
        request: HttpRequest对象
        
    Returns:
        HttpResponse或JsonResponse: 注册成功后重定向或返回JSON响应
    """
    if request.method == 'POST':   #post请求用于验证发送邮箱请求的
        # 检查是否是AJAX请求
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            form = UserRegisterForm(request.POST)
            if form.is_valid():
                # 创建用户但不保存
                user = form.save(commit=False)
                # 设置为未激活状态
                user.is_active = False
                # 保存用户
                user.save()
                
                # 创建用户资料
                UserProfile.objects.create(user=user)
                
                # 创建邮箱验证记录
                token = uuid.uuid4()
                expiration_time = timezone.now() + timezone.timedelta(hours=24)
                EmailVerification.objects.create(
                    user=user,
                    token=token,
                    expiration_time=expiration_time
                )
                
                # 生成6位数验证码
                verification_code = ''.join([str(random.randint(0, 9)) for _ in range(6)])
                
                # 存储验证码到Django缓存，设置过期时间为10分钟
                cache_key = f'email_code_{user.email}'
                cache.set(cache_key, verification_code, 600)
                
                # 获取next参数
                next_url = request.GET.get('next', '')
                
                # 发送验证邮件
                verification_url = request.build_absolute_uri(
                    reverse('verify_email', kwargs={'token': token})
                )
                
                # 如果有next参数，添加到验证URL中
                if next_url:
                    verification_url = f"{verification_url}?next={next_url}"
                
                # 直接发送邮件
                email_sent = False
                try:
                    subject = "商城系统邮箱验证"
                    html_message = f'''
                    <p>尊敬的用户您好！</p>
                    <p>感谢您使用商城系统。</p>
                    <p>您的邮箱为：{user.email}</p>
                    <p>您的验证码为：<strong>{verification_code}</strong>，有效期为10分钟。</p>
                    <p>或者，您也可以点击以下链接完成验证：</p>
                    <p><a href="{verification_url}">{verification_url}</a></p>
                    '''
                    
                    send_mail(
                        subject=subject,
                        message="",
                        from_email=settings.EMAIL_FROM,
                        recipient_list=[user.email],
                        html_message=html_message
                    )
                    email_sent = True
                except Exception as e:
                    logger.error(f"发送验证邮件失败: {e}")
                
                if email_sent:
                    return JsonResponse({'success': True, 'message': '注册成功！请查看您的邮箱获取验证码。', 'email': user.email, 'next_url': next_url})
                else:
                    return JsonResponse({'success': False, 'message': '注册成功，但邮件发送失败，请稍后重试。'})
            else:
                # 表单验证失败，返回错误信息
                errors = {}
                for field, error_list in form.errors.items():
                    errors[field] = [str(error) for error in error_list]
                return JsonResponse({'success': False, 'message': '注册信息有误', 'errors': errors})
        else:
            # 处理常规表单提交
            form = UserRegisterForm(request.POST)
            if form.is_valid():
                # 创建用户但不保存
                user = form.save(commit=False)
                # 设置为未激活状态
                user.is_active = False
                # 保存用户
                user.save()
                
                # 创建用户资料
                UserProfile.objects.create(user=user)
                
                # 创建邮箱验证记录
                token = uuid.uuid4()
                expiration_time = timezone.now() + timezone.timedelta(hours=24)
                EmailVerification.objects.create(
                    user=user,
                    token=token,
                    expiration_time=expiration_time
                )
                
                # 生成6位数验证码
                verification_code = ''.join([str(random.randint(0, 9)) for _ in range(6)])
                
                # 存储验证码到Django缓存，设置过期时间为10分钟
                cache_key = f'email_code_{user.email}'
                cache.set(cache_key, verification_code, 600)
                
                # 获取next参数
                next_url = request.GET.get('next', '')
                
                # 发送验证邮件
                verification_url = request.build_absolute_uri(
                    reverse('verify_email', kwargs={'token': token})
                )
                
                # 如果有next参数，添加到验证URL中
                if next_url:
                    verification_url = f"{verification_url}?next={next_url}"
                
                # 直接发送邮件，不使用Celery
                try:
                    subject = "商城系统邮箱验证"
                    html_message = f'''
                    <p>尊敬的用户您好！</p>
                    <p>感谢您使用商城系统。</p>
                    <p>您的邮箱为：{user.email}</p>
                    <p>您的验证码为：<strong>{verification_code}</strong>，有效期为10分钟。</p>
                    <p>或者，您也可以点击以下链接完成验证：</p>
                    <p><a href="{verification_url}">{verification_url}</a></p>
                    '''
                    
                    send_mail(
                        subject=subject,
                        message="",
                        from_email=settings.EMAIL_FROM,
                        recipient_list=[user.email],
                        html_message=html_message
                    )
                    messages.success(request, '注册成功！请查看您的邮箱并点击验证链接。')
                except Exception as e:
                    logger.error(f"发送验证邮件失败: {e}")
                    messages.error(request, '注册成功，但邮件发送失败，请稍后重试。')
                
                return redirect('login')
    else:
        form = UserRegisterForm()
    
    return render(request, 'user/register.html', {'form': form})


@require_POST
def verify_code(request):
    """
    验证码验证视图 - 通过验证码激活用户账号
    验证用户提交的验证码与缓存中存储的验证码是否匹配
    仅支持AJAX请求
    
    Args:
        request: HttpRequest对象
        
    Returns:
        JsonResponse: 验证结果的JSON响应
    """
    if request.headers.get('X-Requested-With') != 'XMLHttpRequest':
        return JsonResponse({'success': False, 'message': '无效的请求'})
    
    # 获取验证码、邮箱和重定向URL
    verification_code = request.POST.get('verification_code')
    email = request.POST.get('email')
    next_url = request.POST.get('next_url', '')
    
    # 验证参数完整性
    if not verification_code or not email:
        return JsonResponse({'success': False, 'message': '缺少必要参数'})
    
    # 从缓存获取存储的验证码
    cache_key = f'email_code_{email}'
    stored_code = cache.get(cache_key)
    
    # 检查验证码是否存在
    if not stored_code:
        return JsonResponse({'success': False, 'message': '验证码已过期或不存在'})
    
    if verification_code != stored_code:
        return JsonResponse({'success': False, 'message': '验证码错误'})
    
    # 验证成功，激活用户
    try:
        # 获取未激活的用户
        user = User.objects.get(email=email, is_active=False)
        # 激活用户
        user.is_active = True
        user.save()
        
        # 更新用户资料的邮箱验证状态
        profile = UserProfile.objects.get(user=user)
        profile.email_verified = True
        profile.save()
        
        # 删除缓存中的验证码
        cache.delete(cache_key)
        
        # 自动登录用户
        auth_login(request, user)
        
        # 返回重定向URL
        redirect_url = next_url if next_url else reverse('index')
        
        return JsonResponse({
            'success': True, 
            'message': '验证成功', 
            'redirect_url': redirect_url
        })
    except User.DoesNotExist:
        return JsonResponse({'success': False, 'message': '用户不存在或已激活'})


@require_POST
def resend_verification(request):
    """
    重新发送验证码视图 - 为未激活用户重新发送验证码
    生成新的验证码并发送验证邮件
    仅支持AJAX请求
    
    Args:
        request: HttpRequest对象
        
    Returns:
        JsonResponse: 发送结果的JSON响应
    """
    if request.headers.get('X-Requested-With') != 'XMLHttpRequest':
        return JsonResponse({'success': False, 'message': '无效的请求'})
    
    # 获取邮箱和重定向URL
    email = request.POST.get('email')
    next_url = request.POST.get('next_url', '')
    
    # 验证参数完整性
    if not email:
        return JsonResponse({'success': False, 'message': '缺少邮箱参数'})
    
    try:
        # 获取未激活的用户
        user = User.objects.get(email=email, is_active=False)
        
        # 生成新的6位数验证码
        verification_code = ''.join([str(random.randint(0, 9)) for _ in range(6)])
        
        # 存储验证码到Django缓存，设置过期时间为10分钟
        cache_key = f'email_code_{email}'
        cache.set(cache_key, verification_code, 600)
        
        # 获取或创建新的验证记录
        token = uuid.uuid4()
        expiration_time = timezone.now() + timezone.timedelta(hours=24)
        
        # 更新或创建邮箱验证记录
        verification, created = EmailVerification.objects.get_or_create(
            user=user,
            defaults={
                'token': token,
                'expiration_time': expiration_time,
                'is_used': False
            }
        )
        
        # 如果记录已存在，更新其信息
        if not created:
            verification.token = token
            verification.expiration_time = expiration_time
            verification.is_used = False
            verification.save()
        
        # 构建验证链接
        verification_url = request.build_absolute_uri(
            reverse('verify_email', kwargs={'token': token})
        )
        
        # 如果有next参数，添加到验证URL中
        if next_url:
            verification_url = f"{verification_url}?next={next_url}"
        
        # 直接发送邮件，不使用Celery
        email_sent = False
        try:
            subject = "商城系统邮箱验证"
            html_message = f'''
            <p>尊敬的用户您好！</p>
            <p>感谢您使用商城系统。</p>
            <p>您的邮箱为：{email}</p>
            <p>您的验证码为：<strong>{verification_code}</strong>，有效期为10分钟。</p>
            <p>或者，您也可以点击以下链接完成验证：</p>
            <p><a href="{verification_url}">{verification_url}</a></p>
            '''
            
            send_mail(
                subject=subject,
                message="",
                from_email=settings.EMAIL_FROM,
                recipient_list=[email],
                html_message=html_message
            )
            email_sent = True
        except Exception as e:
            logger.error(f"重新发送验证邮件失败: {e}")
        
        # 返回发送结果
        if email_sent:
            return JsonResponse({'success': True, 'message': '验证码已重新发送'})
        else:
            return JsonResponse({'success': False, 'message': '验证码发送失败，请稍后重试'})
    except User.DoesNotExist:
        return JsonResponse({'success': False, 'message': '用户不存在或已激活'})


def verify_email(request, token):
    """
    邮箱验证视图 - 通过验证链接激活用户账号
    验证链接中的token是否有效，并激活对应的用户
    
    Args:
        request: HttpRequest对象
        token: 验证令牌
        
    Returns:
        HttpResponse或JsonResponse: 重定向或JSON响应
    """
    # 获取验证记录，如果不存在则返回404
    verification = get_object_or_404(EmailVerification, token=token)
    next_url = request.GET.get('next', '')
    
    # 检查验证链接是否已被使用
    if verification.is_used:
        messages.info(request, '此验证链接已被使用。')
        return redirect('login')
    
    # 检查验证链接是否已过期
    if verification.is_expired:
        messages.error(request, '此验证链接已过期，请重新注册。')
        return redirect('register')
    
    # 激活用户
    user = verification.user
    user.is_active = True
    user.save()
    
    # 更新用户资料的邮箱验证状态
    profile = UserProfile.objects.get(user=user)
    profile.email_verified = True
    profile.save()
    
    # 标记验证记录为已使用
    verification.is_used = True
    verification.save()
    
    # 自动登录用户
    auth_login(request, user)
    
    # 如果是AJAX请求，返回JSON响应
    if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        return JsonResponse({
            'success': True,
            'message': '邮箱验证成功！您已自动登录。',
            'redirect_url': next_url if next_url else reverse('index')
        })
    
    # 构建重定向URL，带上验证成功参数
    redirect_url = reverse('register') + '?verification_success=true'
    if next_url:
        redirect_url += f'&redirect_url={next_url}'
    else:
        redirect_url += f'&redirect_url={reverse("index")}'
    
    return redirect(redirect_url)


@require_POST
@csrf_exempt
def check_verification_status(request):
    """
    检查邮箱验证状态视图 - 检查用户是否已激活
    用于前端轮询检查用户激活状态
    仅支持AJAX请求
    
    Args:
        request: HttpRequest对象
        
    Returns:
        JsonResponse: 验证状态的JSON响应
    """
    if request.headers.get('X-Requested-With') != 'XMLHttpRequest':
        return JsonResponse({'success': False, 'message': '无效的请求'})
    
    email = request.POST.get('email')
    
    if not email:
        return JsonResponse({'success': False, 'message': '缺少邮箱参数'})
    
    try:
        # 检查用户是否存在且已激活
        user = User.objects.get(email=email)
        profile = UserProfile.objects.get(user=user)
        
        # 如果用户已激活，返回验证成功
        if user.is_active and profile.email_verified:
            # 获取next参数或者referer
            next_url = request.POST.get('next_url', '')
            
            # 如果已经登录了该用户，直接返回跳转信息
            if request.user.is_authenticated and request.user.email == email:
                return JsonResponse({
                    'success': True,
                    'is_verified': True,
                    'message': '邮箱已验证',
                    'redirect_url': next_url if next_url else reverse('index')
                })
            
            # 如果用户还未登录，自动登录
            auth_login(request, user)
            
            return JsonResponse({
                'success': True,
                'is_verified': True,
                'message': '邮箱已验证，已自动登录',
                'redirect_url': next_url if next_url else reverse('index')
            })
        else:
            return JsonResponse({
                'success': True,
                'is_verified': False,
                'message': '邮箱尚未验证'
            })
            
    except (User.DoesNotExist, UserProfile.DoesNotExist):
        return JsonResponse({
            'success': False, 
            'is_verified': False,
            'message': '用户不存在'
        })


@login_required
def logout_view(request):
    """
    用户登出视图 - 处理用户退出登录请求
    清除会话和消息，重定向到首页
    
    Args:
        request: HttpRequest对象
        
    Returns:
        HttpResponse: 重定向到首页
    """
    # 清除所有消息
    storage = get_messages(request)
    # 遍历所有消息以标记它们为已读
    for message in storage:
        pass
    
    # 执行登出
    logout(request)
    messages.success(request, '您已成功退出登录。')
    return redirect('index')


@login_required
def profile_view(request):
    """
    用户个人中心视图 - 显示和更新用户个人资料
    包括基本信息、收货地址和最近订单
    
    Args:
        request: HttpRequest对象
        
    Returns:
        HttpResponse: 渲染后的个人中心页面
    """
    user = request.user
    # 获取或创建用户资料
    profile = UserProfile.objects.get_or_create(user=user)[0]
    
    if request.method == 'POST':
        form = UserProfileForm(request.POST, request.FILES, instance=profile)
        if form.is_valid():
            form.save()
            messages.success(request, '个人资料已更新。')
            return redirect('profile')
    else:
        form = UserProfileForm(instance=profile)
    
    # 获取用户的收货地址
    addresses = Address.objects.filter(user=user)
    
    # 获取用户最近的订单
    recent_orders = Order.objects.filter(user=user).order_by('-created_time')[:3]
    
    # 构建上下文数据
    context = {
        'form': form,
        'addresses': addresses,
        'recent_orders': recent_orders,
    }
    
    return render(request, 'user/profile.html', context)


@login_required
def add_address(request):
    """
    添加收货地址视图 - 处理新增收货地址请求
    支持AJAX请求和普通表单提交
    
    Args:
        request: HttpRequest对象
        
    Returns:
        HttpResponse或JsonResponse: 重定向或JSON响应
    """
    if request.method == 'POST':
        form = AddressForm(request.POST)
        if form.is_valid():
            # 创建新地址并关联到当前用户
            address = form.save(commit=False)
            address.user = request.user
            address.save()
            
            # 检查是否为AJAX请求
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({
                    'success': True,
                    'message': '地址添加成功！',
                    'address_id': address.id
                })
            
            messages.success(request, '地址添加成功！')
            return redirect('profile')
        else:
            # 表单验证失败
            error_msg = '表单验证失败，请检查您的输入！'
            
            # 检查是否为AJAX请求
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                errors = {}
                for field, error_list in form.errors.items():
                    errors[field] = [str(error) for error in error_list]
                return JsonResponse({
                    'success': False,
                    'message': error_msg,
                    'errors': errors
                })
            
            messages.error(request, error_msg)
    
    return redirect('profile')


@login_required
def get_address(request, address_id):
    """
    获取收货地址信息视图 - 返回指定地址的详细信息
    用于前端编辑地址时获取初始数据
    
    Args:
        request: HttpRequest对象
        address_id: 地址ID
        
    Returns:
        JsonResponse: 包含地址信息的JSON响应
    """
    # 获取地址信息，确保只能查看自己的地址
    address = get_object_or_404(Address, id=address_id, user=request.user)
    
    # 返回JSON格式数据
    return JsonResponse({
        'success': True,
        'address': {
            'id': address.id,
            'receiver': address.receiver,
            'province': address.province,
            'city': address.city,
            'district': address.district,
            'address': address.address,
            'zip_code': address.zip_code,
            'phone': address.phone,
            'is_default': address.is_default,
        }
    })


@login_required
def edit_address(request, address_id):
    """
    编辑收货地址视图 - 处理更新收货地址请求
    支持AJAX请求和普通表单提交
    
    Args:
        request: HttpRequest对象
        address_id: 地址ID
        
    Returns:
        HttpResponse或JsonResponse: 重定向或JSON响应
    """
    # 获取地址信息，确保只能编辑自己的地址
    address = get_object_or_404(Address, id=address_id, user=request.user)
    
    if request.method == 'POST':
        form = AddressForm(request.POST, instance=address)
        if form.is_valid():
            form.save()
            
            # 检查是否为AJAX请求
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({
                    'success': True,
                    'message': '地址更新成功！',
                    'address_id': address.id
                })
            
            messages.success(request, '地址更新成功！')
        else:
            # 表单验证失败
            error_msg = '表单验证失败，请检查您的输入！'
            
            # 检查是否为AJAX请求
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                errors = {}
                for field, error_list in form.errors.items():
                    errors[field] = [str(error) for error in error_list]
                return JsonResponse({
                    'success': False,
                    'message': error_msg,
                    'errors': errors
                })
            
            messages.error(request, error_msg)
    
    return redirect('profile')


@login_required
def set_default_address(request, address_id):
    """
    设置默认地址视图 - 将指定地址设为默认收货地址
    支持AJAX请求和普通表单提交
    
    Args:
        request: HttpRequest对象
        address_id: 地址ID
        
    Returns:
        HttpResponse或JsonResponse: 重定向或JSON响应
    """
    if request.method != 'POST':
        # 只接受POST请求
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return JsonResponse({'success': False, 'message': '请求方法不允许'})
        messages.error(request, '请求方法不允许')
        return redirect('profile')
    
    try:
        # 获取要设置为默认的地址，确保它属于当前用户
        address = get_object_or_404(Address, id=address_id, user=request.user)
        
        # 将所有地址设为非默认
        Address.objects.filter(user=request.user, is_default=True).update(is_default=False)
        
        # 设置当前地址为默认
        address.is_default = True
        address.save()
        
        # 检查是否为AJAX请求
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return JsonResponse({'success': True, 'message': '默认地址设置成功！'})
        
        messages.success(request, '默认地址设置成功！')
        return redirect('profile')
    
    except Exception as e:
        # 处理异常
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return JsonResponse({'success': False, 'message': f'设置默认地址失败: {str(e)}'})
        
        messages.error(request, f'设置默认地址失败: {str(e)}')
        return redirect('profile')


@login_required
def delete_address(request, address_id):
    """
    删除收货地址视图 - 删除指定的收货地址
    支持AJAX请求和普通表单提交
    
    Args:
        request: HttpRequest对象
        address_id: 地址ID
        
    Returns:
        HttpResponse或JsonResponse: 重定向或JSON响应
    """
    if request.method != 'POST':
        # 只接受POST请求
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return JsonResponse({'success': False, 'message': '请求方法不允许'})
        messages.error(request, '请求方法不允许')
        return redirect('profile')
    
    try:
        # 获取要删除的地址，确保它属于当前用户
        address = get_object_or_404(Address, id=address_id, user=request.user)
        
        # 检查是否为默认地址
        is_default = address.is_default
        
        # 如果地址已被订单引用，先解除关联
        from orders.models import Order
        Order.objects.filter(address=address).update(address=None)
        
        # 删除地址
        address.delete()
        
        # 如果删除的是默认地址，则设置其他地址为默认（如果有的话）
        if is_default:
            remaining_addresses = Address.objects.filter(user=request.user)
            if remaining_addresses.exists():
                first_address = remaining_addresses.first()
                first_address.is_default = True
                first_address.save()
        
        # 检查是否为AJAX请求
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return JsonResponse({'success': True, 'message': '地址已成功删除！'})
        
        messages.success(request, '地址已成功删除！')
        return redirect('profile')
    
    except Exception as e:
        # 处理异常
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return JsonResponse({'success': False, 'message': f'删除地址失败: {str(e)}'})
        
        messages.error(request, f'删除地址失败: {str(e)}')
        return redirect('profile')


@login_required
def get_all_addresses(request):
    """
    获取用户所有地址列表视图
    用于前端动态加载用户的所有收货地址
    
    Args:
        request: HttpRequest对象
        
    Returns:
        JsonResponse: 包含地址列表的JSON响应
    """
    # 获取当前用户的所有地址
    addresses = Address.objects.filter(user=request.user)
    address_list = []
    
    # 构建地址列表数据
    for address in addresses:
        address_list.append({
            'id': address.id,
            'receiver': address.receiver,
            'province': address.province,
            'city': address.city,
            'district': address.district,
            'address': address.address,
            'phone': address.phone,
            'zip_code': address.zip_code,
            'is_default': address.is_default
        })
    
    return JsonResponse({
        'success': True,
        'addresses': address_list
    })


@login_required
def change_password(request):
    """
    修改密码视图 - 处理用户修改密码请求
    验证当前密码，更新用户密码
    支持AJAX请求和普通表单提交
    
    Args:
        request: HttpRequest对象
        
    Returns:
        HttpResponse或JsonResponse: 重定向或JSON响应
    """
    if request.method == 'POST':
        form = PasswordChangeForm(request.POST)
        if form.is_valid():
            user = request.user
            current_password = form.cleaned_data.get('current_password')
            new_password = form.cleaned_data.get('new_password')
            
            # 验证当前密码
            if not user.check_password(current_password):
                # 当前密码错误
                if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                    return JsonResponse({
                        'success': False,
                        'message': '当前密码不正确',
                        'errors': {'current_password': ['当前密码不正确']}
                    })
                else:
                    messages.error(request, '当前密码不正确')
                    return redirect('change_password')
            
            # 修改密码
            user.set_password(new_password)
            user.save()
            
            # 更新会话，避免用户被登出
            update_session_auth_hash(request, user)
            
            # 返回成功响应
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({
                    'success': True,
                    'message': '密码修改成功'
                })
            else:
                messages.success(request, '密码修改成功')
                return redirect('profile')
        else:
            # 表单验证失败
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                errors = {}
                for field, error_list in form.errors.items():
                    errors[field] = [str(error) for error in error_list]
                return JsonResponse({
                    'success': False,
                    'message': '表单验证失败',
                    'errors': errors
                })
            # 普通表单提交，错误信息会通过form传递到模板
    else:
        form = PasswordChangeForm()
    
    return render(request, 'user/change_password.html', {'form': form})


def forgot_password(request):
    """
    忘记密码视图 - 处理用户忘记密码请求
    发送验证码到用户邮箱
    支持AJAX请求和普通表单提交
    
    Args:
        request: HttpRequest对象
        
    Returns:
        HttpResponse或JsonResponse: 重定向或JSON响应
    """
    # 获取来源URL
    referer_url = request.GET.get('next') or request.META.get('HTTP_REFERER', '')
    
    if request.method == 'POST':
        form = ForgotPasswordForm(request.POST)
        if form.is_valid():
            email = form.cleaned_data.get('email')
            
            # 生成6位数验证码
            verification_code = ''.join([str(random.randint(0, 9)) for _ in range(6)])
            
            # 存储验证码到Django缓存，设置过期时间为10分钟
            cache_key = f'password_reset_code_{email}'
            cache.set(cache_key, verification_code, 600)
            
            # 发送验证码邮件
            try:
                subject = "商城系统密码重置验证码"
                html_message = f'''
                <p>尊敬的用户您好！</p>
                <p>您正在进行密码重置操作。</p>
                <p>您的验证码为：<strong>{verification_code}</strong>，有效期为10分钟。</p>
                <p>如果不是您本人操作，请忽略此邮件。</p>
                '''
                
                send_mail(
                    subject=subject,
                    message="",
                    from_email=settings.EMAIL_FROM,
                    recipient_list=[email],
                    html_message=html_message
                )
                
                # 检查是否为AJAX请求
                if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                    return JsonResponse({
                        'success': True,
                        'message': '验证码已发送到您的邮箱',
                        'email': email
                    })
                
                messages.success(request, '验证码已发送到您的邮箱')
                # 将来源URL作为参数传递
                redirect_url = reverse('verify_reset_code', kwargs={'email': email})
                if referer_url:
                    redirect_url += f'?next={referer_url}'
                return redirect(redirect_url)
            
            except Exception as e:
                logger.error(f"发送密码重置验证码失败: {e}")
                
                if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                    return JsonResponse({
                        'success': False,
                        'message': '验证码发送失败，请稍后重试'
                    })
                
                messages.error(request, '验证码发送失败，请稍后重试')
        else:
            # 表单验证失败
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                errors = {}
                for field, error_list in form.errors.items():
                    errors[field] = [str(error) for error in error_list]
                return JsonResponse({
                    'success': False,
                    'message': '表单验证失败',
                    'errors': errors
                })
    else:
        form = ForgotPasswordForm()
    
    return render(request, 'user/forgot_password.html', {
        'form': form,
        'referer_url': referer_url
    })


def verify_reset_code(request, email):
    """
    验证重置密码验证码视图 - 验证用户输入的验证码
    验证成功后跳转到重置密码页面
    
    Args:
        request: HttpRequest对象
        email: 用户邮箱
        
    Returns:
        HttpResponse: 重定向或渲染页面
    """
    # 获取来源URL
    referer_url = request.GET.get('next', '')
    
    if request.method == 'POST':
        form = VerifyCodeForm(request.POST)
        if form.is_valid():
            verification_code = form.cleaned_data.get('verification_code')
            email = form.cleaned_data.get('email')
            
            # 从缓存获取存储的验证码
            cache_key = f'password_reset_code_{email}'
            stored_code = cache.get(cache_key)
            
            # 检查验证码是否存在
            if not stored_code:
                messages.error(request, '验证码已过期或不存在')
                return redirect('forgot_password')
            
            # 比较验证码
            if verification_code != stored_code:
                messages.error(request, '验证码错误')
                form = VerifyCodeForm(initial={'email': email})
                return render(request, 'user/verify_reset_code.html', {
                    'form': form,
                    'email': email,
                    'referer_url': referer_url
                })
            
            # 验证成功，生成一次性令牌用于重置密码
            reset_token = str(uuid.uuid4())
            cache_key = f'password_reset_token_{email}'
            cache.set(cache_key, reset_token, 1800)  # 30分钟有效期
            
            # 删除验证码缓存
            cache.delete(f'password_reset_code_{email}')
            
            # 将来源URL作为参数传递
            redirect_url = reverse('reset_password', kwargs={'email': email, 'token': reset_token})
            if referer_url:
                redirect_url += f'?next={referer_url}'
            return redirect(redirect_url)
    else:
        # 检查邮箱是否有效
        if not User.objects.filter(email=email).exists():
            messages.error(request, '无效的邮箱地址')
            return redirect('forgot_password')
        
        form = VerifyCodeForm(initial={'email': email})
    
    return render(request, 'user/verify_reset_code.html', {
        'form': form,
        'email': email,
        'referer_url': referer_url
    })


def reset_password(request, email, token):
    """
    重置密码视图 - 用户设置新密码
    验证令牌有效性，更新用户密码
    
    Args:
        request: HttpRequest对象
        email: 用户邮箱
        token: 重置密码令牌
        
    Returns:
        HttpResponse: 重定向或渲染页面
    """
    # 获取来源URL
    referer_url = request.GET.get('next', '')
    
    # 验证令牌有效性
    cache_key = f'password_reset_token_{email}'
    stored_token = cache.get(cache_key)
    
    if not stored_token or stored_token != token:
        messages.error(request, '无效或已过期的密码重置链接')
        return redirect('forgot_password')
    
    if request.method == 'POST':
        form = ResetPasswordForm(request.POST)
        if form.is_valid():
            new_password = form.cleaned_data.get('new_password')
            
            try:
                # 获取用户并更新密码
                user = User.objects.get(email=email)
                user.set_password(new_password)
                user.save()
                
                # 删除令牌缓存
                cache.delete(cache_key)
                
                messages.success(request, '密码重置成功，请使用新密码登录')
                
                # 重定向到登录页面，同时携带next参数
                redirect_url = reverse('login')
                if referer_url:
                    redirect_url += f'?next={referer_url}'
                return redirect(redirect_url)
            
            except User.DoesNotExist:
                messages.error(request, '用户不存在')
                return redirect('forgot_password')
    else:
        form = ResetPasswordForm()
    
    return render(request, 'user/reset_password.html', {
        'form': form,
        'email': email,
        'token': token,
        'referer_url': referer_url
    })